package com.yoyoyo666.report.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.StringUtil;
import com.yoyoyo666.report.common.*;
import com.yoyoyo666.report.mapper.ReportContentMapper;
import com.yoyoyo666.report.mapper.ReportSendLogMapper;
import com.yoyoyo666.report.mapper.ReportUserMapper;
import com.yoyoyo666.report.model.LoginUser;
import com.yoyoyo666.report.model.ReportContent;
import com.yoyoyo666.report.model.ReportSendLog;
import com.yoyoyo666.report.model.ReportUser;
import com.yoyoyo666.report.model.common.BaseResult;
import com.yoyoyo666.report.model.common.ListResult;
import com.yoyoyo666.report.service.SendMailService;
import com.yoyoyo666.report.zento.mapper.*;
import com.yoyoyo666.report.zento.model.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;


@RestController
@RequestMapping("report")
public class ReportController {


    @Autowired
    private ReportContentMapper reportContentMapper;


    @Autowired
    private SendMailService mailService;

    @Autowired
    private ReportSendLogMapper sendLogMapper;

    @Autowired
    private ActionDao actionDao;

    @Autowired
    private BugDao bugDao;

    @Autowired
    private ReportUserMapper reportUserMapper;

    @Autowired
    private ProjectDao projectDao;

    @Autowired
    private ModuleDao moduleDao;

    @Autowired
    private TaskDao taskDao;

    @GetMapping("getAll")
    public ListResult<ReportContent> getContent(@AnnoLogin LoginUser user){
       return  ListResult.getSuccess( reportContentMapper.selectAll(user.getCurrentUser().getId(),null));
    }

    @PostMapping("getAllPage")
    public EasyUIPageResult<ReportContent> getContent(@AnnoLogin LoginUser user, @RequestParam("page") String page, @RequestParam("rows") String row){
        ReportPage reportPage = new ReportPage(Long.valueOf(page), Long.valueOf(row));
        String userId = user.getCurrentUser().getId();
        List<ReportContent> reportContents = reportContentMapper.selectAll(userId, reportPage);
        reportPage.setRecords(reportContents);
        reportPage.setTotal(reportContentMapper.selectAllCount(userId));
        return reportPage.getEuiPage();
    }

    @PostMapping("add")
    public BaseResult add(@AnnoLogin LoginUser user ,ReportContent content){
        int insert = saveContent(user, content);
        if(insert>0){
            return BaseResult.getSuccess();
        }else{
            return BaseResult.getFail();
        }
    }



    private int saveContent(@AnnoLogin LoginUser user, ReportContent content) {
        content.setUserId(user.getCurrentUser().getId());
        content.setId(IDUtils.getId());
        content.setUpdateTime(DateUtils.getNowString());
        content.setCreateTime(DateUtils.getNowStringShort());
        return reportContentMapper.insert(content);
    }

    @PostMapping("addAll")
    public BaseResult add(@AnnoLogin LoginUser user ,String contents){
        List<ReportContent> reportContents = JSON.parseArray(contents, ReportContent.class);
        for (ReportContent content : reportContents) {
            saveContent(user,content);
        }
        return BaseResult.getSuccess();
    }

    @PostMapping("modify")
    public BaseResult modify(@AnnoLogin LoginUser user ,ReportContent content){
        BaseResult fail = BaseResult.getFail();
        //content.setUpdateTime(DateUtils.getNowString());
        if(StringUtil.isEmpty(content.getId())){
            fail.setMsg("id不能为空");
            return fail;
        }

        int insert = reportContentMapper.updateByPrimaryKeySelective(content);
        if(insert>0){
            return BaseResult.getSuccess();
        }else{
            return BaseResult.getFail();
        }
    }

    @PostMapping("delete")
    public BaseResult delete(@AnnoLogin LoginUser user ,ReportContent content){
        BaseResult fail = BaseResult.getFail();
        if(StringUtil.isEmpty(content.getId()) ){
            fail.setMsg("id不能为空");
            return fail;
        }
        List<String> ids = new ArrayList<>();
        String[] split = content.getId().split(",");
        for (String s : split) {
            if(StringUtils.isBlank(s)){
                continue;
            }
            ids.add(s);
        }
        int insert = reportContentMapper.deleteByPrimaryKeys(ids);
        if(insert>0){
            return BaseResult.getSuccess();
        }else{
            return BaseResult.getFail();
        }
    }

    @PostMapping("sendReport")
    public BaseResult sendReport(@AnnoLogin LoginUser user ){

        try {
            boolean b = mailService.sendMail(user.getCurrentUser().getId());

            if(b){
                return BaseResult.getSuccess();
            }else{
                return BaseResult.getFail();
            }

        } catch (Exception e) {
            String stackTrace = ExceptionUtils.getStackTrace(e);
            sendLogMapper.insert(new ReportSendLog(IDUtils.getId(),user.getCurrentUser().getId(),"false",stackTrace));
            e.printStackTrace();
            BaseResult fail = BaseResult.getFail();
            fail.setMsg(stackTrace);
            return fail;
        }
    }

    @GetMapping("getZtContent")
    public ListResult<ReportContent> getZtContent(@AnnoLogin LoginUser user ){

        String username = user.getCurrentUser().getUsername();
        String userid = user.getCurrentUser().getId();
        String name = user.getCurrentUser().getName();

        List<ReportContent> reportContents = getBugReportContents(username, userid,name);
        List<ReportContent> taskContents = getTaskReportContents(username, userid,name);
        reportContents.addAll(taskContents);

        return ListResult.getSuccess(reportContents);

    }

    private List<ReportContent> getBugReportContents( String username, String userid,String name) {
        List<ActionDto> list = getAction(username);
        List<ReportContent> reportContents = new ArrayList<>();

        for (ActionDto actionDto : list) {
            BugTypeEnum valueByType = BugTypeEnum.getValueByType(actionDto.getAction());
            if(valueByType != BugTypeEnum.resolved &&
                    valueByType != BugTypeEnum.bugconfirmed &&
                    valueByType != BugTypeEnum.closed &&
                    valueByType != BugTypeEnum.edited &&
                    valueByType != BugTypeEnum.opened){
                continue;
            }
            ReportContent rc = new ReportContent();
            rc.setUserId(userid);
            rc.setCreateTime(DateUtils.getNowString());
            rc.setUpdateTime(DateUtils.getNowString());
            BugDto bugDto = bugDao.selectById(actionDto.getObjectID());

            ProjectDto project = getProject(String.valueOf(bugDto.getProject()));
            ModuleDto moduleInfo = getModuleInfo(String.valueOf(bugDto.getModule()));

            Date openedDate = bugDto.getOpenedDate();
            String start = DateUtils.sdf2.format(openedDate);
            String end = "";
            if(valueByType == BugTypeEnum.closed || valueByType == BugTypeEnum.resolved){
                end = DateUtils.sdf2.format(actionDto.getDate());
                rc.setStatus("已完成");
            }else{
                rc.setStatus("进行中");
            }
            StringBuffer sb = new StringBuffer();

            sb = addPerson(sb,bugDto.getOpenedBy(),username);
            sb = addPerson(sb,bugDto.getClosedBy(),username);
            sb = addPerson(sb,bugDto.getResolvedBy(),username);
            sb = addPerson(sb,bugDto.getLastEditedBy(),username);

            rc.setPerson(name);
            String title = "";
            if(project!=null){
                title += project.getName() + " ";
            }
            if(moduleInfo!=null){
                title += moduleInfo.getName() + " ";
            }
            title += valueByType.getComment() + "bug 编号：" + actionDto.getObjectID() ;
            rc.setContent(title);
            rc.setContent1( bugDto.getTitle());
            rc.setDepartment("技术部");
            rc.setStartTime(start);
            rc.setEndTime(end);
            rc.setCooperatePerson(sb.toString());
            reportContents.add(rc);
        }
        return reportContents;
    }

    private List<ReportContent> getTaskReportContents( String username, String userid,String name) {
        List<ActionDto> list = getTask(username);
        List<ReportContent> reportContents = new ArrayList<>();

        for (ActionDto actionDto : list) {
            TaskTypeEnum valueByType = TaskTypeEnum.getValueByType(actionDto.getAction());
            if(valueByType != TaskTypeEnum.started &&
                    valueByType != TaskTypeEnum.closed &&
                    valueByType != TaskTypeEnum.finished ){
                continue;
            }
            ReportContent rc = new ReportContent();
            rc.setUserId(userid);
            rc.setCreateTime(DateUtils.getNowString());
            rc.setUpdateTime(DateUtils.getNowString());
            TaskDto taskDto = taskDao.selectById(actionDto.getObjectID());

            ProjectDto project = getProject(String.valueOf(taskDto.getProject()));
            ModuleDto moduleInfo = getModuleInfo(String.valueOf(taskDto.getModule()));

            Date openedDate = taskDto.getOpenedDate();
            String start = DateUtils.sdf2.format(openedDate);
            String end = "";
            if(valueByType == TaskTypeEnum.closed || valueByType == TaskTypeEnum.finished){
                end = DateUtils.sdf2.format(actionDto.getDate());
                rc.setStatus("已完成");
            }else{
                rc.setStatus("进行中");
            }
            StringBuffer sb = new StringBuffer();

            sb = addPerson(sb,taskDto.getOpenedBy(),username);
            sb = addPerson(sb,taskDto.getClosedBy(),username);
            sb = addPerson(sb,taskDto.getLastEditedBy(),username);

            rc.setPerson(name);
            String title = "";
            if(project!=null){
                title += project.getName() + " ";
            }
            if(moduleInfo!=null){
                title += moduleInfo.getName() + " ";
            }
            title += valueByType.getComment() + "任务 编号：" + actionDto.getObjectID() ;
            rc.setContent(title);
            rc.setContent1( taskDto.getName());
            rc.setDepartment("技术部");
            rc.setStartTime(start);
            rc.setEndTime(end);
            rc.setCooperatePerson(sb.toString());
            reportContents.add(rc);
        }
        return reportContents;
    }

    @Cacheable(value = "TEMP_CACHE",key = "methodName + #p0")
    private ProjectDto  getProject (String id ){
        if(StringUtils.isBlank(id)){
            return null;
        }
        return projectDao.selectById(id);
    }

    @Cacheable(value = "TEMP_CACHE",key = "methodName + #p0")
    private ModuleDto getModuleInfo(String id ){
        if(StringUtils.isBlank(id)){
            return null;
        }
        return moduleDao.selectById(id);
    }

    private List<ActionDto> getAction(String name){
        QueryWrapper qw = new QueryWrapper();
        qw.between("date",DateUtils.getDayStart(),DateUtils.getDayEnd());
        qw.eq("actor",name);
        qw.eq("objectType","bug");
        List<ActionDto> list = actionDao.selectList(qw);
        List<ActionDto> newList = new ArrayList<>();
        Map<Integer, List<ActionDto>> collect = list.stream().collect(Collectors.groupingBy(ActionDto::getObjectID));
        collect.forEach((key,value)->{
            Optional<ActionDto> max = value.stream().max((v1, v2) -> {
                if(v1.getId()>v2.getId()){
                    return 1;
                }else if(v1.getId() < v2.getId()){
                    return  -1;
                }
                return 0;
            });
            newList.add(max.get());
        });

        return newList;
    }

    private List<ActionDto> getTask(String name){
        QueryWrapper qw = new QueryWrapper();
        qw.between("date",DateUtils.getDayStart(),DateUtils.getDayEnd());
        qw.eq("actor",name);
        qw.eq("objectType","task");
        List<ActionDto> list = actionDao.selectList(qw);
        List<ActionDto> newList = new ArrayList<>();
        Map<Integer, List<ActionDto>> collect = list.stream().collect(Collectors.groupingBy(ActionDto::getObjectID));
        collect.forEach((key,value)->{
            Optional<ActionDto> max = value.stream().max((v1, v2) -> {
                if(v1.getId()>v2.getId()){
                    return 1;
                }else if(v1.getId() < v2.getId()){
                    return  -1;
                }
                return 0;
            });
            newList.add(max.get());
        });

        return newList;
    }

    private StringBuffer addPerson(StringBuffer sb,String name,String cname){



        if(sb == null){
            sb  = new StringBuffer();
        }

        if(StringUtils.isBlank(name) || name.equals(cname)|| sb.indexOf(name) > -1){
            return sb;
        }


        ReportUser reportUser = selectByUserName(name);

        if(reportUser!=null && sb.length()>0){
            sb.append("、");
            sb.append(reportUser.getName());
        }

        return sb;
    }
    @Cacheable(value = "TEMP_CACHE",key = "methodName + #p0")
    private  ReportUser selectByUserName(String name){
        return  reportUserMapper.selectByUserName(name);
    }

}
